是node package manager的縮寫,也就是node的套件管理工具,只要安裝node就會內建有npm。
首先,要安裝node,可以直接到官網下載安裝。也可以使用另個工具nvm(Node Version Manager)來安裝,一套可以在你電腦切換node版本的工具,使用windows可以在這下載安裝。
nvm常用指令
查看有哪些版本可以下載
nvm list available
下載
nvm install <version>
下載後選擇使用版本nvm install <version>
查看下載那些版本
nvm list
確認node 版本node -v
npm常用指令
npm init
該指令會產生一個package.json檔案,用來記錄專案使用的套件與其版本
{
"name": "",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
安裝套件
在套件頁面的右上都會有下載的指令
npm install <package>
or
npm i <package>
如果使用這指令安裝,安裝的套件會列在package.json的dependencies裡
npm install <package> -D, --save-dev
如果加上-D或是 --save-dev參數,安裝的套件就會列在package.json的devDependencies裡。
{
"dependencies": {},
"devDependencies": {}
}
安裝專案的所有套件
npm install
or
npm i
如果是拿到一個package.json,可以只用該指令來安裝dependencies和devDependencies列的所有套件。
解除安裝
npm uninstall <package>
自訂的指令集
npm run <command>
我們拿一個vite啟的react來看,在scripts裡有dev、build、lint和preview等的command。職協對應的command就會去執行的指令。方便我們來管理指令,這樣也不用什麼套件都安裝成全域使供整台電腦使用。
舉個例子,輸入npm run dev就會去執行vite。
{
"name": "vite-project",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview"
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@types/react": "^18.2.15",
"@types/react-dom": "^18.2.7",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"@vitejs/plugin-react": "^4.0.3",
"eslint": "^8.45.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.3",
"typescript": "^5.0.2",
"vite": "^4.4.5"
}
}
dependencies:在開發的應用程式中會使用到的套件。
devDependencies:在開發的時候會使用到的套件。
如果你是要做在npm上供人下載的套件的話才會有差別。比如你從npm install 下載了某套件,你下載的東西裡就不會有這個某套件的devDependencies上的套件。
然而,因為前端的專案大多都是使用打包出來的檔案,所以用哪一種在運作上其實並沒有差別。
我們可以在devDependencies或dependencies看到我們下載的套件名稱和對應的版本,有著開頭符號與數字的組合,稱之為semantic versioning****。****
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
先從數字來看,版本數字會由3個數字所組成,且用”.”分開像是1.0.2。
我們假設你是個套件的開發者,最初開始的版本官方建議是1.0.0。
再來,如果你的套件有修改一些bug的小變更,那會更新第2個數字,也就是變成1.0.1。
如果之後像是加入一些新功能的中型變更,那就會是更新第2個數字,第3個數字歸0,也就是變成1.1.0。
如果是程式做了一些大變更,大到會無法相容於舊版本那就會更新第1個數字,其他數字歸0,變成2.0.0。
在輸入了npm install
後實際下載到的套件版本會跟數字前的符號有關,可以根據使用的符號來決定要更新到套件的哪個版本。
假設你拿到package.json檔案,有裝一個套件名叫ABC。並且,當下這個套件總釋出2.1.3、2.1.2、2.1.1、2.1.0、1.1.1、1.1.0、1.0.1、1.0.0這幾個版本。
// 狀況1 ~
"dependencies": {
"ABC": "~1.0.0", //如果是這樣就會下載到第3個數字最頂的版本,1.0.x,1.0.1
}
// 狀況2 ^
"dependencies": {
"ABC": "^1.0.0", //如果是這樣就會下載到第2個數字最頂的版本,1.x.x,1.1.1
}
// 狀況2 *
"dependencies": {
"ABC": "*", //如果是這樣就會下載到第2個數字最頂的版本,x.x.x,2.1.3
}
通常,我們比較常看到的是使用^,確保新功能更新又可以向下相容。
前面有提到package.json是紀錄我們安裝的套件與版本,至於package.lock.json除了記錄套件外還有套件使用的套件的細節,在我們使用npm install時候會自動產生,讓我們在測試或者部屬的時候安裝與開發時候相同版本的相依套件。
我們使用npm install
來安裝套件的話,實際安裝的套件就會根據semantic的描述來安裝****。****
如果使用npm ci
搭配package.json與package.lock.json的話,就會根據package.lock.json的版本進行安裝。常使用在上一段我們說到的測試、持續整合等的情境上,鎖定相依套件的版本。
下表為使用指令與使用package.json一個檔案或加上package.lock.json兩個檔案,下載套件的比較表
指令/專案有什麼檔案 | package.json | package.json & |
---|---|---|
npm install | 隨著設定的語意符號更新版本 | lock版號和package相同,下載相同版號檔案,版號不同會以package.json為主作變更,假設有個套件有1.0.1、1.0.2、1.0.33、1.0.36以下情境的下載套件版本結果如下表 |
npm ci | ci指令必須要有package.lock.json才可執行 | 跟json檔一樣的版本(如果本來兩個檔案版本不一致會出現error) |
package.lock.json與package.json版本不同時使用npm install整理表
package.lock.jso | package.json | 下載版本 | |
---|---|---|---|
lock === package | 1.0.2 | ^1.0.2 | 1.0.2 |
lock > package | 1.0.2 | 1.0.1 | 1.0.1 |
1.0.2 | ^1.0.1 | 1.0.2 | |
lock > package | 1.0.2 | 1.0.33 | 1.0.33 |
1.0.2 | ^1.0.33 | 1.0.36 |
我們在下npm install時候,如果下載版本的套件有已知的威脅漏洞報告就會出現提示,如下圖。
可以輸入npm audit列出所有報告的細節
輸入npm audit fix就可以幫你更新套件,行為就像npm install
一樣會安裝,會根據semantic來更新。如果需要有重大更新(就是語意版號第1個數字等級)就會需要使用npm audit fix --force
還有兩個常聽見的管理工具yarn和pnpm,以我的目前的了解使用yarn的安裝速度會比npm還要快,pnpm好像也是這樣,而且對於node_module的結構也有優化。
目前來說雖然有時候npm下載安裝有時候真的是有點久,但是也還可以接受(可以光明正大偷懶說我還在等下載),然後對於npm也比較熟悉,對於其他工具還沒有足夠的誘因使用,所以一直也還沒使用其他兩套工具。